package com.wanban.download.downloadutils

import android.util.Log
import com.wanban.download.WBDownloadUtils
import com.wanban.download.base.BaseDownloadInterface
import com.wanban.download.base.BaseDownloadUtils
import com.wanban.download.db.DownloadEntity
import com.wanban.download.listener.OnFileDownloadListener
import com.wanban.download.listener.OnM3U8ParseListener
import com.wanban.download.model.M3U8
import com.wanban.download.runnable.MultipleThreadDownloadMultipleFilesUtils
import com.wanban.download.runnable.SingleThreadDownloadSingleFileUtils
import com.wanban.download.runnable.MultipleThreadDownloadSingleFileUtils
import com.wanban.download.utils.M3U8ParseUtils
import com.wanban.download.utils.PathUtils
import io.reactivex.Flowable
import io.reactivex.schedulers.Schedulers
import java.util.concurrent.TimeUnit

/**
 * 下载器
 */
class DownloadUtils: BaseDownloadUtils {

    private var interval = false
    private var parseUtils: M3U8ParseUtils? = null
    // 下载队列
    private var downloadUtils: BaseDownloadInterface? = null

    // 启动下载
    override fun startDownload(task: DownloadEntity, listener: OnFileDownloadListener) {
        if (task.m3u8?.tsList?.isNotEmpty() == true) { // 如果已经存在的，不会再次解析
            Log.e("ExchangeManager", "readyToDownload -> ${task.downloadTag} -> 如果已经存在的，不会再次解析....")
            // 准备下载
            if (interval) return
            listener.onStart(task.url)
            // 准备下载
            if (task.m3u8.isMp4) {
                downloadMp4(task.url, task.fileRootPath, task.m3u8.totalLength, listener, task.header)
            } else {
                downloadM3U8(task.url, task.m3u8, task.fileRootPath, listener, task.downloadTag, task.header)
            }
            return
        }

        task.startTaskTime = System.currentTimeMillis()

        Log.e("ExchangeManager", "readyToDownload -> ${task.downloadTag} -> 重新解析....")
        parseUtils?.cancel()
        parseUtils = M3U8ParseUtils()
        parseUtils?.parseUrl(task.url, task.fileRootPath, task.downloadTag, object: OnM3U8ParseListener {
            override fun onParseSuccess(m3u8: M3U8) {
                Log.e("ExchangeManager", "readyToDownload -> ${task.downloadTag} -> 解析成功....")
                Log.d(WBDownloadUtils.TAG, "${task.downloadTag} -> onParseSuccess...是否是MP4:" +m3u8.isMp4)
                if (parseUtils?.isCanceled() == true)  { // 可能因为暂停或者删除等原因，取消了下载
                    return
                }
                parseUtils = null
                task.m3u8 = m3u8
                if (interval) return
                // 准备下载
                if (m3u8.isMp4) {
                    downloadMp4(task.url, task.fileRootPath, m3u8.totalLength, listener, task.header)
                } else {
                    downloadM3U8(task.url, m3u8, task.fileRootPath, listener, task.downloadTag, task.header)
                }
            }

            override fun onParseFail(errMsg: String) {
                Log.e(WBDownloadUtils.TAG, "${task.downloadTag} -> onParseFail...$errMsg")
                if (parseUtils?.isCanceled() == true) { // 可能因为暂停或者删除等原因，取消了下载
                    return
                }
                parseUtils = null
                if (interval) return
                listener.onError(task.url, errMsg)

            }
        }, task.header)
    }

    // 暂停下载
    override fun stopDownload(){
        interval = true
        parseUtils?.cancel()
        parseUtils = null
        downloadUtils?.cancel()
        downloadUtils = null
    }

    // 删除下载
    override fun deleteDownloadFile(task: DownloadEntity) {
        stopDownload()
        Flowable.timer(300, TimeUnit.MILLISECONDS)
            .subscribeOn(Schedulers.io())
            .subscribe({
                PathUtils.deleteTaskFiles(task)
            }, {
                it?.printStackTrace()
            }).isDisposed
    }

    /**
     * 多线程下载单一文件
     *    一个任务最少(#Params.MIN_DOWNLOAD_THREAD_NUMBER)个线程
     *    最多允许(#Params.MAX_DOWNLOAD_QUEUE_RUNNING)个任务同时下载
     */
    private fun downloadMp4(url: String,
                            rootFilePath: String?,
                            totalLength: Long,
                            listener: OnFileDownloadListener?,
                            header: Map<String, String>? = null): Boolean{
        downloadUtils?.cancel()
        val multipleThreadDownloadSingleFileRunnable = MultipleThreadDownloadSingleFileUtils(url, rootFilePath, listener, header)
        // 设置线程池和当前任务的线程数
        multipleThreadDownloadSingleFileRunnable.startDownload(totalLength)
        downloadUtils = multipleThreadDownloadSingleFileRunnable
        return true
    }

    /**
     * 多线程下载文件文件队列
     * @param m3u8 解析到的M3U8数据
     * @param tag task.downloadTag
     */
    private fun downloadM3U8(url: String, m3u8: M3U8, rootFilePath: String?, listener: OnFileDownloadListener, tag: String,
                     header: Map<String, String>? = null): Boolean{
        downloadUtils?.cancel()
        val m3u8DownloadUtils = MultipleThreadDownloadMultipleFilesUtils(url, m3u8, rootFilePath, listener, tag, header)
        m3u8DownloadUtils.startDownload()
        downloadUtils = m3u8DownloadUtils
        return true
    }

    /**
     * 单线程下载单一文件
     */
    fun downloadFileSingleThread(url: String, filePath: String, listener: OnFileDownloadListener?, header: Map<String, String>? = null): Boolean{
        downloadUtils?.cancel()
        val fileDownloadRunnable = SingleThreadDownloadSingleFileUtils(url, filePath, listener, header)
        fileDownloadRunnable.startDownload()
        downloadUtils = fileDownloadRunnable
        return true
    }
}